#pragma once

#ifdef __linux__

#include <string>
#include "knx/platform.h"

extern int gpio_direction(int pin, int dir);
extern int gpio_read(int pin);
extern int gpio_write(int pin, int value);
extern int gpio_export(int pin);
extern int gpio_unexport(int pin);

class LinuxPlatform: public Platform
{
    public:
        LinuxPlatform();
        virtual ~LinuxPlatform();

        void cmdLineArgs(int argc, char** argv);

        std::string flashFilePath();
        void flashFilePath(const std::string path);

        // basic stuff
        void restart() override;
        void fatalError() override;

        // ip config
        uint32_t currentIpAddress() override;
        uint32_t currentSubnetMask() override;
        uint32_t currentDefaultGateway() override;
        void macAddress(uint8_t* data) override;


        //multicast
        void setupMultiCast(uint32_t addr, uint16_t port) override;
        void closeMultiCast() override;
        bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override;
        int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override;
        bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override;

        //UART
        void setupUart() override;
        void closeUart() override;
        int uartAvailable() override;
        size_t writeUart(const uint8_t data) override;
        size_t writeUart(const uint8_t* buffer, size_t size) override;
        int readUart() override;
        size_t readBytesUart(uint8_t* buffer, size_t length) override;

        //spi
        void setupSpi() override;
        void closeSpi() override;
        int readWriteSpi (uint8_t* data, size_t len) override;

        //memory
        uint8_t* getEepromBuffer(uint32_t size) override;
        void commitToEeprom() override;
        void cmdlineArgs(int argc, char** argv);

    private:
        uint32_t _multicastAddr = -1;
        uint16_t _multicastPort = -1;
        int _multicastSocketFd = -1;

        void doMemoryMapping();
        uint8_t* _mappedFile = 0;
        int _fd = -1;
        int _spiFd = -1;
        int _uartFd = -1;
        std::string _flashFilePath = "flash.bin";
        char** _args = 0;

        uint8_t _macAddress[6] = {0, 0, 0, 0, 0, 0};
        uint32_t _ipAddress = 0;
        uint32_t _netmask = 0;
        uint32_t _defaultGateway = 0;
};

#endif
